﻿#region Usings

using System;
using System.Linq;
using System.Xml.Linq;
using FeedReader.Data;

#endregion

namespace FeedReader.Xml
{
    public static class FeedAtomXmlParser
    {
        private static string _cacheFolder;
        private static bool _useCache;

        private static string GetImageUrl(XElement ele, string element)
        {
            XNamespace atom = "http://www.w3.org/2005/Atom";
            /* if (ele != null)
             {
                 if (ele.Attribute("src") != null && ele.Attribute("type") != null)
                 {
                     if ((ele.Attribute("type").Value == "image/png") ||
                         (ele.Attribute("type").Value == "image/gif") ||
                         (ele.Attribute("type").Value == "image/jpg") ||
                         (ele.Attribute("type").Value == "image/jpeg"))
                     {
                         return ele.Element(atom + "content").Attribute("src").Value;
                     }
                 }
             }*/
            try
            {
                if ((ele.Attribute("type").Value == "image/png") ||
                    (ele.Attribute("type").Value == "image/gif") ||
                    (ele.Attribute("type").Value == "image/jpg") ||
                    (ele.Attribute("type").Value == "image/jpeg"))
                {
                    return ele.Element(atom + "content").Attribute("src").Value;
                }
            }
            catch (Exception ex)
            {
                LogEvents.InvokeOnWarning(new FeedArgs("Error parsing string from element " + element, ex.Message, ex.StackTrace));
            }
            return "";
        }

        internal static bool TryParse(XDocument xmlFeed, out Feed feed, string cacheFolder)
        {
            _cacheFolder = cacheFolder;
            _useCache = true;
            return TryParse(xmlFeed, out feed);
        }

        internal static bool TryParse(XDocument xmlFeed, out Feed feed)
        {
            Feed rFeed = new Feed();
            XNamespace atom = "http://www.w3.org/2005/Atom";
            XElement element = xmlFeed.Element(atom + "feed");
            if (element != null)
            {
                LogEvents.InvokeOnDebug(new FeedArgs("This is an ATOM feed. Now parsing the xml data"));
                if (xmlFeed.Descendants(atom + "feed").Elements(atom + "logo") != null)
                {
                    rFeed.ImagePath =
                        FeedXmlParser.ParseString(xmlFeed.Descendants(atom + "feed").Elements(atom + "logo"), "feed/logo");
                }
                else
                {
                    rFeed.ImagePath =
                        FeedXmlParser.ParseString(xmlFeed.Descendants(atom + "feed").Elements(atom + "icon"), "feed/icon");
                }

                rFeed.Description =
                    Utils.Clean(FeedXmlParser.ParseString(xmlFeed.Descendants(atom + "feed").Elements(atom + "subtitle"), "feed/subtitle"));

                rFeed.Title =
                    Utils.Clean(FeedXmlParser.ParseString(xmlFeed.Descendants(atom + "feed").Elements(atom + "title"), "feed/title"));

                try
                {
                    FeedItem feedItem;
                    int i = 1;
                    foreach (XElement entry in xmlFeed.Descendants(atom + "entry"))
                    {
                        feedItem = new FeedItem();
                        feedItem.ImagePath = GetImageUrl(entry, "entry[" + i + "]/content/attribute[source]");
                        feedItem.Author = Utils.Clean(FeedXmlParser.ParseString(entry.Descendants(atom + "author").Elements(atom + "name"), "entry[" + i + "]/author/name"));
                        feedItem.Title = Utils.Clean(FeedXmlParser.ParseString(entry.Element(atom + "title"), "entry[" + i + "]/title"));
                        feedItem.Url = FeedXmlParser.ParseString(entry.Element(atom + "link"), "href", "entry[" + i + "]/link/attribute[href]").Trim();
                        feedItem.PublishDate = FeedXmlParser.ParseDateTime(entry.Element(atom + "updated"), "entry[" + i + "]/updated");
                        string description = FeedXmlParser.ParseString(entry.Element(atom + "summary"), "entry[" + i + "]/summary");
                        if (string.IsNullOrEmpty(feedItem.ImagePath))
                        {
                            LogEvents.InvokeOnDebug(new FeedArgs("Try to get feed[" + rFeed.Title + "][" + feedItem.Title + "][" + i + "] image out of summary field..."));
                            feedItem.ImagePath = Utils.GetImageOutOfDescription(description);
                        }
                        feedItem.Description = Utils.Clean(description);
                        rFeed.Items.Add(feedItem);
                        i++;
                    }
                    /*rFeed.Items = (from entry in xmlFeed.Descendants(atom + "entry")
                                   select new FeedItem
                                              {
                                                  ImagePath = GetImageUrl(entry, "entry/content/attribute[source]"),
                                                  Author =
                                                      FeedXmlParser.ParseString(
                                                      entry.Descendants(atom + "author").Elements(atom + "name"), "entry/author/name"),
                                                  Title =
                                                      Utils.Clean(
                                                      FeedXmlParser.ParseString(entry.Element(atom + "title"),"entry/title")),
                                                  Url = FeedXmlParser.ParseString(entry.Element(atom + "link"), "href", "entry/link/attribute[href]"),
                                                  PublishDate =
                                                      FeedXmlParser.ParseDateTime(entry.Element(atom + "updated"), "entry/updated"),
                                                  Description =
                                                      Utils.Clean(
                                                      FeedXmlParser.ParseString(entry.Element(atom + "summary"), "entry/summary")),
                                              }).OrderByDescending(feedItem => feedItem.PublishDate).ToList();*/
                    LogEvents.InvokeOnInfo(new FeedArgs("Try to get feed images either from cache or from download links"));
                    feed = _useCache ? Utils.DownloadImages(rFeed, _cacheFolder) : Utils.DownloadImages(rFeed);
                    feed.Items = feed.Items.OrderByDescending(fItem => fItem.PublishDate).ToList();
                    LogEvents.InvokeOnDebug(new FeedArgs("Parsing of ATOM feed done. See above for possibly errors or warnings"));
                    return true;
                }
                catch (Exception ex)
                {
                    LogEvents.InvokeOnError(new FeedArgs("Error parsing ATOM feed", ex.Message, ex.StackTrace));
                    feed = null;
                    return false;
                    //throw new FeedDownloadErrorExpection("Error downloading from URL: " + Url);
                }
            }
            LogEvents.InvokeOnDebug(new FeedArgs("This is not an ATOM feed or the downloaded xml file is not a valid feed"));
            feed = null;
            return false;
            //throw new FeedDownloadErrorExpection("Error downloading from URL: " + Url);
        }
    }
}